import datetime
from collections import OrderedDict

from sqlalchemy import and_

from webapp.models import ScheduleTable, VCourse, Grade, CourseTable, Session
from webapp.tools import download_bord_excel, download_excel


class BoardService:

    @staticmethod
    def gradeBoard(gradeId):
        finalBoard = []
        # 最后返回的样式为
        #         ['1', '', '', '', '', '', '', ''],
        #         ['', '2', '', '', '', '', '', ''],
        #         ['', '', '3', '3', '', '', '', ''],
        #         ['', '', '', '', '4', '4', '', ''],
        #         ['', '', '', '', '', '', '5', '5']
        # 获取当前学期ID
        session = BoardService.get_cur_session()
        # 以班级为纬度，查询出该班级的所有课的安排
        scheduleTables = ScheduleTable.query.filter(ScheduleTable.classId == gradeId,
                                                    ScheduleTable.sessionId == session.id).all()
        # 先把这个班级关联的课整理出来
        courses = set()
        for scheduleTable in scheduleTables:
            courses.add(scheduleTable.courseId)
        # 循环该set集合，取出每个课程，对其进行统计
        # 班级名称、教师名称
        cname = ''
        tname = ''
        classname = ''
        for courseId in courses:
            courseInfo = VCourse.query.filter(VCourse.id == courseId).first()
            # 统计一下这个课，在第某节的排课情况
            cname = courseInfo.cname
            tname = courseInfo.tname
            roomname = courseInfo.roomname
            for i in range(5):
                boardArr = []
                for j in range(0, 7, 2):
                    weekCollction = set()
                    weekstr = ''
                    boardStr = ''
                    # 以大课为单位排的课，以大课为单位统计
                    scheduleWithOrders = ScheduleTable.query.filter(ScheduleTable.courseId == courseId,
                                                                    ScheduleTable.order == j,
                                                                    ScheduleTable.weekorder == i).order_by(
                        ScheduleTable.weeknum).all()
                    if len(scheduleWithOrders) > 0:
                        for scheduleWithOrder in scheduleWithOrders:
                            weekCollction.add(scheduleWithOrder.weeknum)
                        weekstr = ','.join(str(i) for i in weekCollction)
                        boardStr = '{}@{}\n{}\n上课周:{}'.format(cname, roomname, tname, weekstr)
                        boardArr.append(boardStr)
                        boardArr.append(boardStr)
                    else:
                        boardArr.append('')
                        boardArr.append('')
                        continue
                finalBoard.append(boardArr)
        return finalBoard

    @staticmethod
    def boardGradeExportExcel(gradeId):
        grade = Grade.query.filter(Grade.id == gradeId).first()
        excelData = BoardService.gradeBoard(grade.id)
        contents = []
        for edata in excelData:
            data = OrderedDict()
            data["星期"] = "周一"
            data["课程"] = edata[0]
            contents.append(data)
        return download_excel(contents)

    @staticmethod
    def teacherBoard(teacherId):
        finalBoard = []
        # 最后返回的样式为
        #         ['1', '', '', '', '', '', '', ''],
        #         ['', '2', '', '', '', '', '', ''],
        #         ['', '', '3', '3', '', '', '', ''],
        #         ['', '', '', '', '4', '4', '', ''],
        #         ['', '', '', '', '', '', '5', '5']
        # tempFinalBoard，考虑到教师会有多个班级的课，所以每节课需要一个数组去保存
        tempFinalBoard = []
        # 获取当前学期ID
        session = BoardService.get_cur_session()
        # 以班级为纬度，查询出该班级的所有课的安排
        scheduleTables = ScheduleTable.query.filter(ScheduleTable.teacherId == teacherId,
                                                    ScheduleTable.sessionId == session.id).all()
        # 先把这个班级关联的课整理出来
        courses = set()
        # 取出课程id，放入set去重
        for scheduleTable in scheduleTables:
            courses.add(scheduleTable.courseId)
        # 循环该set集合，取出每个课程，对其进行统计
        # 班级名称、教师名称
        cname = ''
        classname = ''
        # 保存排课信息
        tempFinalBoard = [[[''] for i in range(8)] for j in range(5)]
        for courseId in courses:
            # 根据课程ID，查询课程信息
            courseInfo = VCourse.query.filter(VCourse.id == courseId).first()
            # 统计一下这个课，在第某节的排课情况
            cname = courseInfo.cname
            classId = courseInfo.teachclass
            roomname = courseInfo.roomname
            classname = courseInfo.classname
            # 统计该课程的信息
            for i in range(5):
                # 每天的课程安排，放入这个数组
                for j in range(0, 7, 2):
                    weekCollction = set()
                    weekstr = ''
                    boardStr = ''
                    # 每天中的每节课的课程安排,放入这个数组
                    boardArrSeciton = tempFinalBoard[i][j]
                    # 以大课为单位排的课，以大课为单位统计
                    scheduleWithOrders = ScheduleTable.query.filter(ScheduleTable.classId == classId,
                                                                    ScheduleTable.courseId == courseId,
                                                                    ScheduleTable.order == j,
                                                                    ScheduleTable.weekorder == i,
                                                                    ScheduleTable.sessionId == session.id).order_by(
                        ScheduleTable.weeknum).all()
                    if len(scheduleWithOrders) > 0:
                        for scheduleWithOrder in scheduleWithOrders:
                            weekCollction.add(scheduleWithOrder.weeknum)
                        weekstr = ','.join(str(i) for i in weekCollction)
                        boardStr = '{}@{}\n{}\n上课周:{}'.format(cname, roomname, classname, weekstr)
                        ## 一个老师可能会有给不同的班级在不同的周上课，所以会出现同一节课不同的班级
                        boardArrSeciton.append(boardStr)
                    else:
                        boardStr = ''
                        boardArrSeciton.append(boardStr)
        for i in range(5):
            # 每天的课程安排，放入这个数组
            weekstr = ''
            tempDay = []
            for j in range(0, 7, 2):
                boardArrSeciton = tempFinalBoard[i][j]
                weekstr = ''.join(boardArrSeciton[i] for i in range(len(boardArrSeciton)))
                tempDay.append(weekstr)
                tempDay.append(weekstr)
            finalBoard.append(tempDay)
        return finalBoard

    @staticmethod
    def get_cur_session():
        # 获取当前学期ID
        cur_session_date = datetime.datetime.now()
        session = Session.query.filter(and_(
            Session.begin_date <= cur_session_date,
            Session.end_date >= cur_session_date
        )).order_by(Session.create_time).first()
        return session

    @staticmethod
    def roomBoard(roomId):
        finalBoard = []
        # 最后返回的样式为
        #         ['1', '', '', '', '', '', '', ''],
        #         ['', '2', '', '', '', '', '', ''],
        #         ['', '', '3', '3', '', '', '', ''],
        #         ['', '', '', '', '4', '4', '', ''],
        #         ['', '', '', '', '', '', '5', '5']
        # tempFinalBoard，考虑到教师会有多个班级的课，所以每节课需要一个数组去保存
        tempFinalBoard = []
        # 获取当前学期ID
        session = BoardService.get_cur_session()
        # 以班级为纬度，查询出该班级的所有课的安排
        scheduleTables = ScheduleTable.query.filter(ScheduleTable.placeId == roomId,
                                                    ScheduleTable.sessionId == session.id).all()
        # 先把这个班级关联的课整理出来
        courses = set()
        # 取出课程id，放入set去重
        for scheduleTable in scheduleTables:
            courses.add(scheduleTable.courseId)
        # 循环该set集合，取出每个课程，对其进行统计
        # 班级名称、教师名称
        cname = ''
        classname = ''
        # 保存排课信息
        tempFinalBoard = [[[''] for i in range(8)] for j in range(5)]
        for courseId in courses:
            # 根据课程ID，查询课程信息
            courseInfo = VCourse.query.filter(VCourse.id == courseId).first()
            # 统计一下这个课，在第某节的排课情况
            cname = courseInfo.cname
            placeId = courseInfo.resource
            tname = courseInfo.tname
            classname = courseInfo.classname
            # 统计该课程的信息
            for i in range(5):
                # 每天的课程安排，放入这个数组
                for j in range(0, 7, 2):
                    weekCollction = set()
                    weekstr = ''
                    boardStr = ''
                    # 每天中的每节课的课程安排,放入这个数组
                    boardArrSeciton = tempFinalBoard[i][j]
                    # 以大课为单位排的课，以大课为单位统计
                    scheduleWithOrders = ScheduleTable.query.filter(ScheduleTable.placeId == placeId,
                                                                    ScheduleTable.courseId == courseId,
                                                                    ScheduleTable.order == j,
                                                                    ScheduleTable.weekorder == i,
                                                                    ScheduleTable.sessionId == session.id).order_by(
                        ScheduleTable.weeknum).all()
                    if len(scheduleWithOrders) > 0:
                        for scheduleWithOrder in scheduleWithOrders:
                            weekCollction.add(scheduleWithOrder.weeknum)
                        weekstr = ','.join(str(i) for i in weekCollction)
                        boardStr = '{}@{}\n{}\n上课周:{}'.format(cname, tname, classname, weekstr)
                        ## 一个教室可能会安排给不同的班级在不同的周上课，所以会出现同一节课不同的班级
                        boardArrSeciton.append(boardStr)
                    else:
                        boardStr = ''
                        boardArrSeciton.append(boardStr)
        for i in range(5):
            # 每天的课程安排，放入这个数组
            weekstr = ''
            tempDay = []
            for j in range(0, 7, 2):
                boardArrSeciton = tempFinalBoard[i][j]
                weekstr = ''.join(boardArrSeciton[i] for i in range(len(boardArrSeciton)))
                tempDay.append(weekstr)
                tempDay.append(weekstr)
            finalBoard.append(tempDay)
        return finalBoard

    @staticmethod
    def select_course_schedule(data):
        deptId = data.get('deptId')
        weeknum = data.get('weeknum')
        finalBoard = []
        # 最后返回的样式为
        #         ['1', '', '', '', '', '', '', ''],
        #         ['', '2', '', '', '', '', '', ''],
        #         ['', '', '3', '3', '', '', '', ''],
        #         ['', '', '', '', '4', '4', '', ''],
        #         ['', '', '', '', '', '', '5', '5']
        # 获取当前学期ID
        session = BoardService.get_cur_session()
        scheduleTables = ScheduleTable.query.filter(ScheduleTable.classId == deptId,
                                                    ScheduleTable.sessionId == session.id,
                                                    ScheduleTable.weeknum == weeknum).all()
        # 先把这个班级关联的课整理出来
        courses = set()
        for scheduleTable in scheduleTables:
            courses.add(scheduleTable.courseId)
        # 循环该set集合，取出每个课程，对其进行统计
        # 班级名称、教师名称
        for courseId in courses:
            courseInfo = VCourse.query.filter(VCourse.id == courseId).first()
            # 统计一下这个课，在第某节的排课情况
            cname = courseInfo.cname
            tname = courseInfo.tname
            roomname = courseInfo.roomname
            for i in range(5):
                boardArr = []
                for j in range(0, 7, 2):
                    weekCollction = set()
                    # 以大课为单位排的课，以大课为单位统计
                    scheduleWithOrders = ScheduleTable.query.filter(ScheduleTable.courseId == courseId,
                                                                    ScheduleTable.order == j,
                                                                    ScheduleTable.weekorder == i).all()

                    if len(scheduleWithOrders) > 0:
                        for scheduleWithOrder in scheduleWithOrders:
                            weekCollction.add(scheduleWithOrder.weeknum)
                        boardStr = '{}@{}\t{}'.format(cname, roomname, tname)
                        boardArr.append(boardStr)
                        boardArr.append(boardStr)
                    else:
                        boardArr.append('')
                        boardArr.append('')
                        continue
                finalBoard.append(boardArr)
        return finalBoard
